package org.hiro.psi;

import com.intellij.codeInsight.generation.PsiElementClassMember;
import com.intellij.psi.PsiField;
import org.apache.commons.lang.StringUtils;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;
import org.hiro.CodeGenerationException;
import org.hiro.velocity.VelocityFactory;

import java.io.StringWriter;

public class GeneratedBuilderHelper {
    private static final String WITH_METHOD_TEMPLATE = "public $className with$capitilizedFieldName($fieldType $fieldName) { ";
    private static final String WITH_METHOD_RETURN = "return this; }";

    public static final String WITH_METHOD_BASIC_TEMPLATE = WITH_METHOD_TEMPLATE +
            "this.$fieldName = $fieldName;" +
            WITH_METHOD_RETURN;

    public static final String WITH_METHOD_VALUEMAP_TEMPLATE = WITH_METHOD_TEMPLATE +
            "values.put(\"$fieldName\", $fieldName);" +
            WITH_METHOD_RETURN;

    public static String getWithMethodText(PsiElementClassMember field, String className, String template) throws CodeGenerationException {
        PsiField psiField = (PsiField) field.getElement();

        VelocityContext velocityContext = new VelocityContext();
        velocityContext.put("fieldName", psiField.getName());
        velocityContext.put("capitilizedFieldName", StringUtils.capitalize(psiField.getName()));
        velocityContext.put("fieldType", psiField.getType().getPresentableText());
        velocityContext.put("className", className);

        StringWriter stringWriter = new StringWriter();
        populateTemplate(stringWriter, velocityContext, template);

        return stringWriter.getBuffer().toString();
    }

    private static void populateTemplate(StringWriter stringWriter, VelocityContext velocityContext, String withMethodTemplate) throws CodeGenerationException {
        try {
            VelocityEngine velocity = VelocityFactory.getVelocityEngine();
            velocity.evaluate(velocityContext, stringWriter, null, withMethodTemplate);
        } catch (Exception exception) {
            exception.printStackTrace();
            throw new CodeGenerationException("Error creating with method");
        }
    }
}
